<template>
  <div>
    <HETTable1
      ref="portRulesTable"
      :tableData="data.tableData"
      :tHead="data.tHead"
      :headerOperation="
        !treeStore.isShowStrategyDetail ? data.headerOperation : []
      "
      :checkBox="treeStore.isShowStrategyDetail ? false : true"
      :total="data.total"
      @chooseData="chooseData"
      @getTableData="getPortRuleList"
    >
      <template #icon>
        <el-table-column :width="40">
          <template #default="scope">
            <div class="imgWarp">
              <img
                v-if="scope.row.enable"
                title="放行"
                :src="img1"
                width="15"
              />
              <img
                title="拦截"
                v-if="!scope.row.enable"
                :src="img2"
                width="15"
              />
            </div>
          </template>
        </el-table-column>
      </template>
      <template #direction>
        <el-table-column label="方向">
          <template #default="scope">
            {{ scope.row.direction === 1 ? "出站" : "入站" }}
          </template>
        </el-table-column>
      </template>
      <template #protocol>
        <el-table-column label="协议">
          <template #default="scope">
            {{ scope.row.protocol === 0 ? "TCP" : "UDP" }}
          </template>
        </el-table-column>
      </template>
      <template #localPort>
        <el-table-column label="本地端口">
          <template #default="scope">
            {{ scope.row.localPort == "" ? "任何" : scope.row.localPort }}
          </template>
        </el-table-column>
      </template>
      <template #remoteAddress>
        <el-table-column label="远程地址">
          <template #default="scope">
            {{
              scope.row.remoteAddress == "" ? "任何" : scope.row.remoteAddress
            }}
          </template>
        </el-table-column>
      </template>
      <template #enable>
        <el-table-column label="拦截">
          <template #default="scope">
            <el-switch
              v-model="scope.row.enable"
              :active-value="0"
              :inactive-value="1"
              :loading="loading"
              :disabled="treeStore.isShowStrategyDetail"
              @change="changeEnable(scope.row)"
            >
            </el-switch>
          </template>
        </el-table-column>
      </template>
    </HETTable1>
    <el-dialog
      title="新建端口白名单"
      :model-value="dialogAsync"
      :center="true"
      width="35%"
      :destroy-on-close="true"
      :close-on-click-modal="false"
      @open="openDialog"
    >
      <div class="stepBox">
        <el-steps :active="active" finish-status="success">
          <el-step v-for="(item, i) in step" :key="i" :title="item"> </el-step>
        </el-steps>
      </div>
      <p class="stepTitle">{{ step[active] }}</p>
      <div class="fromWarp">
        <el-form
          ref="formRef"
          status-icon
          :model="form"
          :rules="rules"
          label-width="auto"
        >
          <!--规则类型 -->
          <div class="rule" v-if="active === 0">
            <el-form-item label="适用规则" prop="direction">
              <el-radio-group v-model="form.direction">
                <el-radio :value="2">入站规则</el-radio>
                <el-radio v-if="!isOldOs" :value="1">出站规则</el-radio>
              </el-radio-group>
            </el-form-item>
            <el-form-item :label="step[0]" prop="ruleType">
              <div class="radiowarp">
                <el-radio v-model="form.ruleType" :value="0">端口(O)</el-radio>
                <p class="describe">控制TCP或UDP端口连接的规则</p>
              </div>
            </el-form-item>
          </div>
          <!-- 协议和端口 -->
          <div class="protocol" v-if="active === 1">
            <el-form-item
              label="协议"
              prop="protocol"
              v-if="form.localPortType != 2"
            >
              <el-select
                v-model="form.protocol"
                popper-class="success"
                placeholder="请选择协议"
              >
                <el-option label="TCP" :value="0"></el-option>
                <el-option label="UDP" :value="1"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="本地端口" prop="localPortType">
              <el-select
                v-model="form.localPortType"
                popper-class="success"
                placeholder="请选择"
              >
                <el-option v-if="!isOldOs" label="所有本地端口" :value="0"></el-option>
                <el-option label="特定本地端口" :value="1"></el-option>
                <el-option
                  v-if="isOldOs"
                  label="选择本地程序"
                  :value="2"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              v-if="form.localPortType === 1"
              prop="localPort"
              label-width="76px"
            >
              <el-input v-model.trim="form.localPort" class="input-form">
              </el-input>
              <div class="describe textindent0">示例：80</div>
            </el-form-item>
            <el-form-item v-if="form.localPortType === 2" label-width="76px">
              <!-- 选择本地程序 -->
              <div class="baseDiv">
                <div class="diySty" v-show="form.desc">
                  <span style="margin-right: 5px">{{ form.desc }}</span>
                  <el-icon @click="form.desc = ''"><CircleClose /></el-icon>
                  <br />
                </div>
              </div>
              <el-button @click="treeStore.directoryDialogVModel = true" style="margin-left: 10px"
                >选择程序</el-button
              >
            </el-form-item>
            <el-form-item
              label="远程地址"
              prop="remoteAddressType"
              v-if="!isOldOs"
            >
              <el-select
                v-model="form.remoteAddressType"
                popper-class="success"
              >
                <el-option label="任何IP地址" :value="0"> </el-option>
                <el-option label="特定IP地址" :value="1"> </el-option>
              </el-select>
            </el-form-item>
            <el-form-item
              v-if="form.remoteAddressType === 1"
              prop="remoteAddress"
              label-width="76px"
            >
              <el-input v-model.trim="form.remoteAddress" class="input-form">
              </el-input>
              <div class="describe textindent0">示例：192.168.1.1</div>
            </el-form-item>
          </div>
          <!-- 处理动作 -->
          <div class="operation" v-if="active === 2">
            <el-form-item label="处理动作" prop="enable">
              <el-radio-group v-model="form.enable">
                <el-radio :value="1">允许连接</el-radio>
                <div class="describe"></div>
                <el-radio :value="0">阻止连接</el-radio>
                <div class="describe"></div>
              </el-radio-group>
            </el-form-item>
          </div>
          <div class="name" v-if="step.length - 1 === active">
            <el-form-item label="名称" prop="ruleName">
              <div class="name" style="width: 100%">
                <el-input v-model.trim="form.ruleName" class="input-form">
                </el-input>
              </div>
            </el-form-item>

            <el-form-item label="描述" prop="desc" v-if="!isOldOs">
              <el-input
                type="textarea"
                wrap="off"
                clearable
                maxlength="256"
                rows="6"
                show-word-limit
                v-model="form.desc"
              >
              </el-input>
            </el-form-item>
          </div>
        </el-form>
      </div>
      <template #footer>
        <div class="butWarp">
          <el-button @click="pre()" class="right" v-show="active !== 0"
            >上一步</el-button
          >
          <el-button
            @click="next(formRef)"
            class="right"
            :loading="loading"
            type="primary"
            >{{ step.length - 1 === active ? "完成" : "下一步" }}</el-button
          >
          <el-button class="left" @click="dialogAsync = false"> 取消</el-button>
        </div>
      </template>
    </el-dialog>
    <directory-dialog :typeRestrictions="['exe']" @handleDialogButton="choosePath" :os="treeStore.osType"></directory-dialog>
  </div>
</template>

<script setup>
import img1 from "~/assets/images/deploy@2x.png";
import img2 from "~/assets/images/noActivedeploy.png";
import { ref, reactive, onMounted, markRaw, onUnmounted } from "vue";
import { useTreeStore } from "~/utils/pinia/tree.js";
import { ElMessage, ElMessageBox } from "element-plus";
import { Search, Refresh, Delete, Plus } from "@element-plus/icons-vue";
import { validPort, validIp } from "~/utils/common/validation.js";
import {
  req_getPortRules,
  req_portIntercept,
  req_addPortRule,
  req_delPortRules,
} from "~/utils/axios/index.js";
import { eventBus } from "~/utils/common/eventBus.js";
eventBus.on("getStrategyDetail", (detail) => {
  data.tableData = detail.data;
  data.total = detail.total;
});
const treeStore = useTreeStore();
const portRulesTable = ref();
treeStore.treeLinkedTableRef = portRulesTable;
const dialogAsync = ref(false);
const isOldOs = ref(false);
const getRulename = () => {
  //根据时间生成名称，精确到秒
  let date = new Date();
  let year = date.getFullYear();
  let month = date.getMonth() + 1;
  if (month < 10) {
    month = "0" + month;
  }
  let day = date.getDate();
  if (day < 10) {
    day = "0" + day;
  }
  let hour = date.getHours();
  if (hour < 10) {
    hour = "0" + hour;
  }
  let minutes = date.getMinutes();
  if (minutes < 10) {
    minutes = "0" + minutes;
  }
  let seconds = date.getSeconds();
  if (seconds < 10) {
    seconds = "0" + seconds;
  }
  return `FW-${year}${month}${day}${hour}${minutes}${seconds}`;
};
const formRef = ref();
const form = ref({
  desc: "",
  direction: 2,
  enable: 1,
  localAddress: "",
  localAddressType: 0,
  localPort: "",
  localPortType: 0,
  operate: 0,
  priority: 2,
  protocol: 0,
  remoteAddress: "",
  remoteAddressType: 0,
  remotePort: "",
  remotePortType: 0,
  ruleName: "",
  ruleType: 0,
});
// 验证默认网关是否在同一子网中

const validName = (rule, value, callback) => {
  if (value == 'all' || value == 'ALL') {
    callback(new Error('不能输入该名称'))
  } else {
    callback()
  }
}

const rules = ref({
  ruleName: [
    { required: true, message: "规则名称不能为空", trigger: "blur" },
    { validator: validName, message: "不能输入该名称", trigger: "blur" },
  ],
  localPort: [
    { required: true, message: "本地端口不能为空", trigger: "blur" },
    { validator: validPort, trigger: "blur" },
  ],
  remoteAddress: [
    { required: true, message: "远程地址不能为空", trigger: "blur" },
    { validator: validIp, trigger: "blur" },
  ],
});
const step = ref(["规则类型", "协议和端口", "处理动作", "名称"]);
const active = ref(0);

const openDialog = () => {
  form.value = {
    desc: "",
    direction: 2,
    enable: 1,
    localAddress: "",
    localAddressType: 0,
    localPort: "",
    localPortType: isOldOs.value?1:0,
    operate: 0,
    priority: 2,
    protocol: 0,
    remoteAddress: "",
    remoteAddressType: 0,
    remotePort: "",
    remotePortType: 0,
    ruleName: getRulename(),
    ruleType: 0,
  };
  active.value = 0
  if (["WindowsXP", "Windows2003"].includes(treeStore.osVersion)) {
    isOldOs.value = true;
  } else {
    isOldOs.value = false;
  }
};
const delPortRules = () => {
  let params = data.selectData.map((item) => {
    return {
      id: item.id,
      priority: item.priority,
      ruleName: item.ruleName,
    };
  });
  ElMessageBox.confirm("确定要删除选中的规则？", "删除端口规则", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    center: true,
    closeOnClickModal: false,
  }).then(() => {
    req_delPortRules(treeStore.treeDeviceId, params).then((res) => {
      res.data.succeed
        ? ElMessage.success("删除成功")
        : ElMessage.error("删除失败");
      portRulesTable.value.getTableData();
    });
  });
};
const data = reactive({
  tHead: [
    {
      label: "展开列",
      prop: "expand",
      isCustom: true,
      slotName: "expand",
    },
    {
      label: "icon",
      prop: "icon",
      isCustom: true,
      slotName: "icon",
    },
    {
      label: "名称",
      prop: "ruleName",
      isCustom: false,
    },
    {
      label: "方向",
      prop: "direction",
      isCustom: true,
      slotName: "direction",
    },
    {
      label: "本地端口",
      prop: "localPort",
      isCustom: true,
      slotName: "localPort",
    },
    {
      label: "远程地址",
      prop: "remoteAddress",
      isCustom: true,
      slotName: "remoteAddress",
    },
    {
      label: "协议",
      prop: "protocol",
      isCustom: true,
      slotName: "protocol",
    },
    {
      label: "拦截",
      prop: "enable",
      isCustom: true,
      slotName: "enable",
    },
  ],
  tableData: [],
  headerOperation: [
    {
      name: "新建规则",
      icon: markRaw(Plus),
      handleClick: () => {
        dialogAsync.value = true;
      },
    },
    {
      name: "删除",
      icon: markRaw(Delete),
      handleClick: delPortRules,
    },
  ],
  selectData: [],
  total: null, // 数据总条数
});
// 多选
const chooseData = (selectData) => {
  data.selectData = selectData;
};
const choosePath = (ref, path) => {
  form.value.desc = path
}
const loading = ref(false);
const changeEnable = (row) => {
  loading.value = true;
  req_portIntercept(treeStore.treeDeviceId, row)
    .then((res) => {
      loading.value = false;
      res.data.succeed
        ? ElMessage.success("操作成功")
        : ElMessage.error("操作失败");
      portRulesTable.value.getTableData();
    })
    .catch((err) => {
      loading.value = false;
    });
};

const pre = () => {
  active.value -= 1;
};
const next = (formEl) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      if (step.value.length - 1 === active.value) {
        loading.value = true;
        req_addPortRule(treeStore.treeDeviceId, form.value)
          .then((res) => {
            loading.value = false;
            if (res.data.succeed) {
              ElMessage.success("新建成功");
              dialogAsync.value = false;
              portRulesTable.value.getTableData();
            } else {
              ElMessage.error("新建失败");
            }
          })
          .catch((err) => {
            loading.value = false;
          });
      } else {
        active.value += 1;
      }
    }
  });
};
const getPortRuleList = async (initTableParams, $filter) => {
  if (!treeStore.treeDeviceId || treeStore.osType != 'win') return;
  portRulesTable.value.loading(); // 表格加载开始
  try {
    const { data: res } = await req_getPortRules(
      treeStore.treeDeviceId,
      initTableParams
    );
    portRulesTable.value.finish(); // 表格加载完成
    loading.value = false; // 停止开关的加载状态
    data.tableData = res.firewallConfigList || [];
    data.total = res.total || 0;
    data.selectData = [];
  } catch (err) {
    portRulesTable.value.finish(); // 表格加载完成
    loading.value = false; // 停止开关的加载状态
  }
};
</script>

<style lang="scss" scoped>
.stepTitle {
  background: rgba($color: #000000, $alpha: 0.1);
  height: 33px;
  line-height: 33px;
  margin: 15px -20px;
  text-indent: 20px;
  font-size: 16px;
}
:deep(.el-dialog__body) {
  height: 420px;
}
:deep(.el-step.is-horizontal .el-step__line) {
  top: 9px;
}
:deep(.el-step__icon) {
  width: 18px;
  height: 18px;
}
:deep(.el-step__title) {
  font-size: 14px;
}
.describe {
  font-size: 12px;
  line-height: 25px;
  color: #888;
}
.formWarp {
  .input-form {
    width: 300px !important;
  }
}
.baseDiv {
  width: 300px;
  height: 80px;
  background: rgba(0, 0, 0, 0.1);
  overflow: auto;
  border: 1px solid transparent;
  padding: 6px;
  box-sizing: border-box;
}

.diySty {
  background: rgba(0, 0, 0, 0.25);
  border-radius: 2px;
  text-align: left;
  line-height: 29px;
  cursor: pointer;
  padding-left: 6px;
  padding-right: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
}
</style>
